﻿
using Dora.Orm.SqlSugarCore.UnitOfWork;
using Dora.Services.AdminUser.Dto.QueryDto;
using Dora.Services.AdminUser.Entities;
using Dora.Services.AdminUser.IApplication;
using Dora.Services.AdminUser.Repository.Repositorys;
using Dora.Tools.Utility.Const;
using Microsoft.Extensions.Logging;
using Surging.Core.Common;
using Surging.Core.CPlatform.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dora.Services.AdminUser.Application.Base;
using Dora.Tools.Enums.AdminUser;
using Dora.Tools.Enums;
using Dora.Tools.Utility;

namespace Dora.Services.AdminUser.Application
{
    /// <summary>
    /// 权限表服务
    /// </summary>
    [ModuleName(DoraModuleName.AdminUser)]
    public class PermissionService : DoraServiceBase, IPermissionService
    {
        
        private ISugarUnitOfWork _unitOfWork;
        private readonly PermissionRepository repository;
        private readonly DoraUserRepository doraUserRepository;
        private readonly TasUserRepository tasUserRepository;
        private readonly SrmUserRepository srmUserRepository;
        private readonly RolePermissionMapRepository rolePermissionMapRepository;
        public PermissionService(ISugarUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            repository = new PermissionRepository(unitOfWork);
            doraUserRepository = new DoraUserRepository(unitOfWork);
            tasUserRepository = new TasUserRepository(unitOfWork);
            srmUserRepository = new SrmUserRepository(unitOfWork);
            rolePermissionMapRepository = new RolePermissionMapRepository(unitOfWork);
        }


        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultDto<PermissionEntity>> Create(PermissionEntity entity)
        {
            entity.CreatedTime = DateTime.Now;
            entity.UpdatedTime = DateTime.Now;
            entity.Id = await repository.GetMaxId() + 1;

            var parentPath = "";
            PermissionEntity parent = null;
            if (entity.SystemId <= 0 || string.IsNullOrWhiteSpace(entity.SystemKey))
            {
                return ResultDto<PermissionEntity>.Error("请选择系统");
            }
            if (entity.ParentId > 0)
            {
                parent = await GetById(entity.ParentId);
                #region 更新父级的HasSub
                if (parent == null)
                {
                    return ResultDto<PermissionEntity>.Error("上级不存在");
                }
                parent.HasSub = 1;
                await repository.UpdateHasSub(parent);
                #endregion
                entity.LevelIdx = parent.LevelIdx + 1;
                parentPath = parent.LevelPath;
            }
            else
            {
                entity.LevelIdx = 0;
            }

            try
            {
                var result = await repository.InsertAsync(entity);
                if (result != null)
                {
                    entity.Id = result.Id;
                    entity.LevelPath = $"{parentPath}{result.Id},";
                    var authKey = $"";
                    if (parent == null)
                    {
                        authKey = $"{entity.SystemId}-{entity.Id}";
                    }
                    else
                    {
                        authKey = $"{parent.AuthKey}-{entity.Id}";
                    }
                    entity.AuthKey = authKey;
                    await repository.UpdateLevelPath(entity);
                    await repository.UpdateAuthKey(entity);
                    return ResultDto<PermissionEntity>.Success(result);
                }
                else
                {
                    return ResultDto<PermissionEntity>.Error("创建失败");
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }


        /// <summary>
        /// 根据Id获取一个实体对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<PermissionEntity> GetById(int id)
        {
            return await repository.FirstOrDefaultAsync(id);
        }


        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageDataList<PermissionEntity>> GetPageList(PermissionQueryDto input)
        {
            var page = await repository.GetPageList(input);
            return page;
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultDto> Update(PermissionEntity entity)
        {
            entity.UpdatedTime = DateTime.Now;
            var result= await repository.Update(entity);
            if (result)
            {
                return ResultDto.Success("修改成功");
            }
            else
            {
                return ResultDto.Error("修改失败");
            }
        }

        /// <summary>
        /// 根据IdList获取列表
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public async Task<List<PermissionEntity>> GetList(List<int> idList)
        {
            if (idList == null || idList.Count == 0)
            {
                return new List<PermissionEntity>();
            }
            var list =await repository.GetAllListAsync(it => idList.Contains(it.Id));
            return list;
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public async Task<List<PermissionEntity>> GetAll()
        {
            var list =await repository.GetAllListAsync();
            return list;
        }

        public async Task<List<PermissionEntity>> GetByParentId(int parentId)
        {
            return await repository.GetAllListAsync(it => it.ParentId == parentId);
        }

        public async Task<bool> ExistAuthKey(int permissionId, string authKey)
        {
            var result= await repository.GetAllListAsync(it => it.AuthKey == authKey.ToLower().Trim() && it.IsDeleted == 0 && it.Id != permissionId);
            return result.Count > 0;
        }

        public async Task<ResultDto<int>> ImportList(List<PermissionEntity> list)
        {
            if (list == null || list.Count == 0)
            {
                return new ResultDto<int>(ResultCode.Fail, "没有需要导入的权限", 0);
            }
            var num = 0;
            foreach (var item in list)
            {
                var entity = await GetById(item.Id);
                if (entity == null)
                {
                    var existKey = await ExistAuthKey(0, item.AuthKey);
                    if (existKey)
                    {
                        return new ResultDto<int>(ResultCode.Fail, $"AuthKey[{item.AuthKey}]已经存在", num);
                    }
                    #region create
                    item.CreatedTime = DateTime.Now;
                    item.UpdatedTime = DateTime.Now;
                    var result = await repository.InsertAsync(item);
                    if (result !=null)
                    {
                        num++;
                    }
                    #endregion
                }
                else
                {
                    var existKey = await ExistAuthKey(item.Id, item.AuthKey);
                    if (existKey)
                    {
                        return new ResultDto<int>(ResultCode.Fail, $"AuthKey[{item.AuthKey}]已经存在", num);
                    }
                    #region update
                    item.UpdatedTime = DateTime.Now;
                    var result = await repository.UpdateAsync(item);
                    if (result)
                    {
                        num++;
                    }
                    #endregion
                }
            }
            return new ResultDto<int>(ResultCode.Success, "导入成功", num);
        }

        public async Task<List<PermissionEntity>> GetDoraAuthedListByMenuId(Guid userId, int menuId)
        {
            return await repository.GetDoraAuthedListByMenuId(userId,menuId);
        }

        public async Task<List<string>> GetDoraAuthKeyList(Guid userId)
        {
            var authKeyList = new List<string>();
            var userEntity = await doraUserRepository.FirstOrDefaultAsync(userId);
            if (userEntity == null)
            {
                return authKeyList;
            }
            var permissions = new List<PermissionEntity>();
            if (userEntity.IsSuperAdmin == 1)
            {
                permissions = await repository.GetAllListAsync(it => it.SystemKey == DoraSysIdentifier.DAS.ToDescription() && it.IsDeleted == 0);
            }
            else
            {
                permissions = await repository.GetDoraAuthedListByUserId(userId);
            }
            if (permissions?.Count > 0)
            {
                authKeyList = permissions.Select(p => p.AuthKey).ToList();
            }
            return authKeyList;
        }

        public async Task<List<string>> GetTasAuthKeyList(Guid userId,int orgId)
        {
            var authKeyList = new List<string>();
            var userEntity = await tasUserRepository.FirstOrDefaultAsync(userId);
            if (userEntity == null)
            {
                return authKeyList;
            }
            var permissions = new List<PermissionEntity>();
            if (userEntity.IsSuperAdmin == 1)
            {
                permissions = await repository.GetAllListAsync(it => it.SystemKey == DoraSysIdentifier.TAS.ToDescription() && it.IsDeleted == 0);
            }
            else
            {
                permissions = await repository.GetTasAuthedListByUserIdAndOrgId(userId, orgId);
            }
            if (permissions?.Count > 0)
            {
                authKeyList = permissions.Select(p => p.AuthKey).ToList();
            }
            return authKeyList;
        }

        public async Task<List<string>> GetSrmAuthKeyList(Guid userId)
        {
            var authKeyList = new List<string>();
            var userEntity = await srmUserRepository.FirstOrDefaultAsync(userId);
            if (userEntity == null)
            {
                return authKeyList;
            }
            var permissions = new List<PermissionEntity>();
            if (userEntity.IsSuperAdmin == 1)
            {
                permissions = await repository.GetAllListAsync(it => it.SystemKey == DoraSysIdentifier.SRM.ToDescription() && it.IsDeleted == 0);
            }
            else
            {
                permissions = await repository.GetSrmAuthedListByUserId(userId);
            }
            if (permissions?.Count > 0)
            {
                authKeyList = permissions.Select(p => p.AuthKey).ToList();
            }
            return authKeyList;
        }

        /// <summary>
        /// 获取用户所有的权限KeyList，根据角色
        /// </summary>
        /// <param name="roleIdList">角色id</param>
        /// <returns></returns>
        public async Task<List<string>> GetDoraAuthKeyListByRoleIdList(List<Guid> roleIdList)
        {
            var authKeyList = new List<string>();
            var permissions = await repository.GetDoraListByRoleIdList(roleIdList);

            if (permissions?.Count > 0)
            {
                authKeyList = permissions.Select(p => p.AuthKey).ToList();
            }

            return authKeyList;
        }

        /// <summary>
        /// 通过authkey获取下级所有权限
        /// </summary>
        /// <param name="authKey"></param>
        /// <returns></returns>
        public async Task<List<PermissionEntity>> GetListByParentAuthKey(string authKey)
        {
            var parent = await repository.FirstOrDefaultAsync(it=>it.AuthKey==authKey&&it.IsDeleted==0);
            if (parent == null)
            {
                return new List<PermissionEntity>();
            }
            return await repository.GetAllListAsync(p => p.ParentId == parent.Id && p.IsDeleted == 0);
        }

        /// <summary>
        /// 通过authkey获取员工某个菜单下拥有的所有权限
        /// </summary>
        /// <param name="EmployeeId"></param>
        /// <param name="MenuId"></param>
        /// <returns></returns>
        public async Task<List<PermissionEntity>> GetDoraAuthedListByParentAuthKey(Guid userId, string authKey)
        {
            var parent = await repository.FirstOrDefaultAsync(it => it.AuthKey == authKey && it.IsDeleted == 0);
            if (parent == null)
            {
                return new List<PermissionEntity>();
            }
            return await repository.GetDoraAuthedListByMenuId(userId, parent.Id);
        }

        public async Task<ResultDto> Delete(PermissionEntity entity)
        {
            var hasSub = await repository.HasSub(entity.Id);
            if (hasSub)
            {
                return ResultDto.Error( "权限存在下级，不能被删除");
            }

            var usedRoleList = await rolePermissionMapRepository.GetListByPermissionId(entity.Id);
            if (usedRoleList?.Count > 0)
            {
                var roleNameList = usedRoleList.Select(p => p.RoleName);
                var roleNames = string.Join(',', roleNameList.ToArray());
                return ResultDto.Error($"权限被下列角色包含[{roleNames}]，不能被删除");
            }

            entity.UpdatedTime = DateTime.Now;
            try
            {
                var result = await repository.Delete(entity);
                #region 修改父级的HasSub
                if (result)
                {
                    var parent = await GetById(entity.ParentId);
                    if (parent != null)
                    {
                        hasSub = await repository.HasSub(entity.ParentId);
                        parent.HasSub = hasSub ? (short)1 : (short)0;
                        await repository.UpdateHasSub(parent);
                    }
                }
                #endregion

                return new ResultDto(ResultCode.Success, result ? "删除成功" : "删除失败", result);
            }
            catch(Exception ex)
            {
                return ResultDto.Error("删除失败");
            }
           
        }
    }
}
